#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@File ：__init__.py
@Author ：zqy
@Email : zqingy@work@163.com
@note: 视图层
"""

from flask_restx import Namespace
from flask_restx import Resource

from application.middleware.AuthMiddleware import auth_required
from application.util.ResponseUtil import ResponseUtil


def register_crud_model(
        ns: Namespace,
        logic_cls,
        parser,
        route="/",
        roles=None,
        id_type="int",
        tag="CRUD",
        include_operations=None
):
    """
    注册通用的CRUD模型
    :param ns: Namespace对象
    :param logic_cls: 逻辑类
    :param parser: parser参数校验类
    :param roles: 角色列表
    :param route: 路由
    :param id_type: ID类型
    :param tag: 标签
    """

    get_p = parser.get()
    post_p = parser.post()
    put_p = parser.put()

    include_operations = include_operations or ["get", "list", "post", "put", "delete"]

    class _List(Resource):

        if "post" in include_operations:
            @ns.expect(post_p)
            def post(self):
                return ResponseUtil(data=logic_cls.add(post_p.parse_args())).success()
        if "list" in include_operations:
            # @auth_required(roles)
            @ns.expect(get_p)
            def get(self):
                return ResponseUtil(data=logic_cls.get_list(get_p.parse_args())).success()

    class _Detail(Resource):

        if "get" in include_operations:
            def get(self, id):
                return ResponseUtil(data=logic_cls.get_info_by_id(id)).success()

        if "put" in include_operations:
            # @auth_required(roles)
            @ns.expect(put_p)
            def put(self, id):
                return ResponseUtil(data=logic_cls.update_by_id(id, put_p.parse_args())).success()

        if "delete" in include_operations:
            @auth_required(roles)
            def delete(self, id):
                logic_cls.delete_by_ids(id)
                return ResponseUtil(message=f"删除成功 ID={id}").success()

    _List.__name__ = f"{tag}ListResource"
    _Detail.__name__ = f"{tag}DetailResource"

    ns.add_resource(_List, route)
    ns.add_resource(_Detail, f"{route}/<{id_type}:id>")
